/**
 * Created by wust on 2019-11-01 10:14:28
 * Copyright © 2019 wust. All rights reserved.
 */
package com.sc.admin.core.api.open.user;


import com.sc.admin.core.service.SysUserService;
import com.sc.common.annotations.OpenApi;
import com.sc.common.annotations.OperationLog;
import com.sc.common.dto.WebResponseDto;
import com.sc.common.entity.admin.account.SysAccount;
import com.sc.common.entity.admin.user.SysUser;
import com.sc.common.enums.ApplicationEnum;
import com.sc.common.enums.OperationLogEnum;
import com.sc.common.util.RC4;
import com.sc.common.util.cache.DataDictionaryUtil;
import com.sc.common.util.cache.SpringRedisTools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author: wust
 * @date: Created in 2019-11-01 10:14:28
 * @description: app员工登录：账号密码登录
 *
 */
@Api(tags = {"开放接口~app员工账号密码登陆"})
@OpenApi
@RequestMapping("/api/open/v1/AppUserLoginByAccountOpenApi")
@RestController
public class AppUserLoginByAccountOpenApi extends AppUserLoginBase {
    static Logger logger = LogManager.getLogger(AppUserLoginByAccountOpenApi.class);

    @Autowired
    private SpringRedisTools springRedisTools;

    @Autowired
    private SysUserService sysUserServiceImpl;

    @Override
    protected SpringRedisTools getSpringRedisTools() {
        return springRedisTools;
    }


    @ApiOperation(value = "App登陆：员工通过账号密码登陆", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name="loginName",value="登陆账号",required=true,paramType="query"),
            @ApiImplicitParam(name="password",value="登陆口令（使用32位小写MD5密文，如0192023a7bbd73250516f069df18b500）",required=true,paramType="query"),
            @ApiImplicitParam(name="lang",value="语言（如zh-CN）",required=true,paramType="query")
    })
    @OperationLog(moduleName= OperationLogEnum.MODULE_COMMON,businessName="App账号密码登录",operationType= OperationLogEnum.Login)
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public WebResponseDto login(@RequestParam("loginName") String loginName,
                                @RequestParam("password") String password,
                                @RequestParam("lang") String lang) {
        WebResponseDto responseDto = new WebResponseDto();

        String passwordRC4 = RC4.encry_RC4_string(password.toUpperCase(),ApplicationEnum.LOGIN_RC4_KEY.getStringValue());

        SysAccount account = DataDictionaryUtil.getAccountByCode(loginName);
        if(account == null) {
            logger.warn("登录失败：此账号[{}]不存在",loginName);
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("账号或密码错误"); // 不应提示太明确，防止恶意碰撞攻击
            return responseDto;
        }

        if(!passwordRC4.equals(account.getPassword())){
            logger.warn("登录失败：此账号[{}]的密码输入有误",loginName);
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("账号或密码错误"); // 不应提示太明确，防止恶意碰撞攻击
            return responseDto;
        }


        SysUser sysUserSearch = new SysUser();
        sysUserSearch.setLoginName(loginName);
        sysUserSearch.setStatus("A102901");
        SysUser sysUser = sysUserServiceImpl.selectOne(sysUserSearch);
        if(sysUser == null){
            responseDto.setFlag(WebResponseDto.INFO_WARNING);
            responseDto.setMessage("您没有入职或没有权限登陆系统");
            return responseDto;
        }


        /**
         * 由于app的token保存时间太长，客户端有可能会丢失token，为了防止客户端丢失token而后台token没有过期问题，此处需要先判断删除，否则可能会造成空间浪费
         */
        String[] tokens = createToken(loginName);
        String redisKey = tokens[0];
        String tokenBase64 = tokens[1];

        String keyPrefix = redisKey.substring(0,redisKey.lastIndexOf('=')) + "*";
        if(keyPrefix.contains("APP_LOGIN_KEY=" + loginName)){
            Set<String> keys = springRedisTools.keys(keyPrefix);
            if(keys != null && keys.size() > 0){
                springRedisTools.deleteByKey(keys);
            }
        }

        final Map<String,Object> mapValue = new HashMap<>();
        mapValue.put(ApplicationEnum.X_AUTH_TOKEN.getStringValue(),tokenBase64);
        mapValue.put(ApplicationEnum.X_LOCALE.getStringValue(),lang);
        appendUserToUserContext(mapValue,sysUser);
        appendProjectToUserContext(mapValue,sysUser.getId());
        responseDto.setObj(mapValue);
        springRedisTools.addMap(redisKey,mapValue,ApplicationEnum.X_APP_AUTH_TOKEN_EXPIRE_TIME.getIntValue(), TimeUnit.MINUTES);
        return responseDto;
    }
}
